﻿using DotNetty.Common.Utilities;
using DotNetty.Transport.Channels;
using System;
using System.Threading.Tasks;
using System.Collections;
using DotNetty.Transport.Bootstrapping;

namespace YanShu.Utils
{
    class ClientChannelMannager
    {

        private static AttributeKey<Boolean> USER_CHANNEL_WRITEABLE = AttributeKey<Boolean>.NewInstance("user_channel_writeable");

        private static AttributeKey<Boolean> CLIENT_CHANNEL_WRITEABLE = AttributeKey<Boolean>.NewInstance("client_channel_writeable");

        private static int MAX_POOL_SIZE = 100;

        private static Hashtable realServerChannels = new Hashtable();

        private static Queue proxyChannelPool = new Queue();

        private static volatile IChannel cmdChannel;

        static readonly String server = Constants.INET_HOST;

        static readonly int port = Constants.INET_PORT;


        public static async Task<IChannel> BorrowProxyChanelAsync(Bootstrap bootstrap)
        {
            if (proxyChannelPool.Count > 0)
            {
                IChannel channel = (IChannel)proxyChannelPool.Dequeue();
                if (channel != null)
                {
                    return channel;
                }
            }

            IChannel channel1 = await bootstrap.ConnectAsync(server, port);
            return channel1;
        }
        public static void AddRealServerChannel(String userId, IChannel realServerChannel)
        {
            realServerChannels.Add(userId, realServerChannel);
        }

        public static void SetRealServerChannelUserId(IChannel realServerChannel, String userId)
        {
            realServerChannel.GetAttribute(Constants.USER_ID).Set(userId);
        }
        public static void ReturnProxyChanel(IChannel proxyChanel)
        {
            if (proxyChannelPool.Count > MAX_POOL_SIZE)
            {
                proxyChanel.CloseAsync();
            }
            else
            {
                proxyChanel.Configuration.SetOption(ChannelOption.AutoRead, true);
                proxyChanel.GetAttribute(Constants.NEXT_CHANNEL).Remove();
                //添加代理信道到队列末尾
                proxyChannelPool.Enqueue(proxyChanel);
            }
        }
        public static void RemoveProxyChanel(IChannel proxyChanel)
        {
            //暂用Dequeue，代理java的ConcurrentLinkedQueue
            MainWindow.SetText("proxyChannelPool=" + proxyChannelPool.Count);
            if (proxyChannelPool.Count > 0)
            {
                //移除队列先进信道
                proxyChannelPool.Dequeue();
            }
        }
        public static String GetRealServerChannelUserId(IChannel realServerChannel)
        {
            return realServerChannel.GetAttribute(Constants.USER_ID).Get();
        }
        public static void SetCmdChannel(IChannel cmdChannel)
        {
            ClientChannelMannager.cmdChannel = cmdChannel;
        }
        public static IChannel GetCmdChannel()
        {
            return cmdChannel;
        }
        public static void ClearRealServerChannels()
        {
            
            // 关闭所有信道后，清空哈希表
            realServerChannels.Clear();


        }

        public static void RemoveRealServerChannel(String userId)
        {
            realServerChannels.Remove(userId);
        }
    }

}

